/**
 * Project Reactor
 */


#include "Acceptor.h"
#include <iostream>
using std::endl;
using std::cout;

/**
 * Acceptor implementation
 */


/**
 * @param port
 */
Acceptor::Acceptor(unsigned short port)
:_addr(port)
,_sock()
{


}

/**
 * @param on
 * @return void
 */
void Acceptor::setReuseAddr(bool on) {
    if(on)
    {
        int opt = 1;
        int ret = setsockopt(_sock.fd(), SOL_SOCKET, 
                             SO_REUSEADDR, &opt, sizeof(opt));
        if(ret == -1)
        {
            perror("setsockopt");
        }


    }
    else
    {
        int opt = 0;
        int ret = setsockopt(_sock.fd(), SOL_SOCKET, 
                             SO_REUSEADDR, &opt, sizeof(opt));
        if(ret == -1)
        {
            perror("setsockopt");
        }

    }
}

/**
 * @param on
 * @return void
 */
void Acceptor::setReusePort(bool on) {
    if(on)
    {
        int opt = 1;
        int ret = setsockopt(_sock.fd(), SOL_SOCKET, 
                             SO_REUSEPORT, &opt, sizeof(opt));
        if(ret == -1)
        {
            perror("setsockopt");
        }


    }
    else
    {
        int opt = 0;
        int ret = setsockopt(_sock.fd(), SOL_SOCKET, 
                             SO_REUSEPORT, &opt, sizeof(opt));
        if(ret == -1)
        {
            perror("setsockopt");
        }

    }


}

/**
 * @return void
 */
void Acceptor::bind() {
    if(::bind(_sock.fd(), (struct sockaddr *)_addr.getInetAddressPtr(),
              sizeof(struct sockaddr)) < 0)
    {
        perror("bind");
    }
}

/**
 * @return void
 */
void Acceptor::listen() {
    cout << "listening sockfd" << _sock.fd() << endl;
    if(::listen(_sock.fd(), 128) < 0)
    {
        perror("listen");
    }
}

/**
 * @return int
 */
int Acceptor::accept() {
    int peerfd;
    if((peerfd = ::accept(_sock.fd(),NULL, NULL)) < 0)
    {
        perror("accept");
    }
    return peerfd;
    
}

/**
 * @return void
 */
void Acceptor::ready() {
    setReuseAddr(true);
    setReusePort(true);
    bind();
    listen();
}
